/**
 * ****************************************************************************
 * Project: RoboBridge
 * ----------------------------------------------------------------------------
 * -------------------------- [c]2012 - KrawallMann ---------------------------
 * ---------------------- http://www.krawallmann.de.tc/ -----------------------
 * ****************************************************************************
 * File: Writer.java Package: tc.de.krawallmann.robobridge.communication
 * Version: 1.0 Author(s): KrawallMann
 * ****************************************************************************
 * Description:
 * ****************************************************************************
 */
package tc.de.krawallmann.robobridge.communication;

import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;

import tc.de.krawallmann.robobridge.util.Exceptions;

/**
 * The Class Writer writes to an OutputStream.
 * 
 * @author KrawallMann
 * @version 1.0
 */
public class Writer {

	/** The listeners. */
	public transient Set<OutgoingMessageListener> listeners =
			new HashSet<OutgoingMessageListener>();

	/** The connectedState. */
	private transient boolean connectedState;

	/** The last bitrate. */
	private transient long lastBitrate;

	/** The print writer. */
	private transient PrintWriter printWriter;

	/**
	 * Adds the outgoing message listener.
	 * 
	 * @param listener
	 *            the listener
	 * @return true, if successful
	 */
	public boolean addOutgoingMessageListener(final OutgoingMessageListener listener) {
		if (listener == null) {
			throw Exceptions.onNullPointer(this, "listener");
		}
		return listeners.add(listener);
	}

	/**
	 * Clear outgoing message listeners.
	 */
	public void clearOutgoingMessageListeners() {
		listeners.clear();
	}

	/**
	 * Close.
	 */
	public void close() {
		if (connectedState) {
			printWriter.close();
			connectedState = false;
		}
	}

	/**
	 * Connect.
	 * 
	 * @param outputStream
	 *            the output stream
	 */
	public void connect(final OutputStream outputStream) {
		if (outputStream == null) {
			throw Exceptions.onNullPointer(this, "outputStream");
		}
		if (connectedState) {
			throw new IllegalStateException("Writer already connected!");
		}
		printWriter = new PrintWriter(outputStream);
		connectedState = true;
	}

	/**
	 * Gets the last bitrate.
	 * 
	 * @return the last bitrate
	 */
	public long getLastBitrate() {
		return lastBitrate;
	}

	/**
	 * Gets the outgoing message listener count.
	 * 
	 * @return the outgoing message listener count
	 */
	public int getOutgoingMessageListenerCount() {
		return listeners.size();
	}

	/**
	 * Checks if is the reader is connected.
	 * 
	 * @return true, if it is connected
	 */
	public boolean isConnected() {
		return connectedState;
	}

	/**
	 * Removes the outgoing message listener.
	 * 
	 * @param listener
	 *            the listener
	 * @return true, if successful
	 */
	public boolean removeOutgoingMessageListener(final OutgoingMessageListener listener) {
		if (listener == null) {
			throw Exceptions.onNullPointer(this, "listener");
		}
		return listeners.remove(listener);
	}

	/**
	 * Write.
	 * 
	 * @param text
	 *            the text
	 */
	public void write(final String text) {
		if (text == null) {
			throw Exceptions.onNullPointer(this, "text");
		}
		if (!connectedState) {
			throw new IllegalStateException("Writer: Not connectedState!");
		}
		for (final OutgoingMessageListener l : listeners) {
			l.onMessageSent(text);
		}
		printWriter.println(text);
		printWriter.flush();
	}
}
